package es.uned.dia.james;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.ListIterator;

public class Delay {
    private LinkedList<double[]> schedule;
    private double L;

    // Constructor
    public Delay(double L) {
        schedule = new LinkedList<double[]>();
        this.L = L;
    }
    
    // Change the value of the time delay
    public void setDelay(double L) {
        if(L<0) return;
        this.L = L;
    }

    // Adds a new delayed control action. 
    // This method DOES NOT CHECK whether the time is valid or not. 
    public void add(double time, double value) {   	
        double[] newValue = {time+L, value};
        
        schedule.addLast(newValue);
    }
    
    // Removes all tj < sup {ti | ti < time) 
    public boolean advance(double time) {
    	double[] next;
    	
    	while((next = schedule.peekFirst()) != null) {
    		if(time > next[0]) return true; 
    		schedule.removeFirst();
    	}
    	
    	return false;    	
    }

    // Returns the value of the control action at the specified 'time'
    public double u(double time) {
    	double[] current, next = null;
   	
    	ListIterator<double[]> read = schedule.listIterator();

    	// empty buffer or time < first time
    	if(!read.hasNext() || time < (current = read.next())[0]) return 0.0;
    	// find sup {ti | ti <= time < ti+1}
    	while(read.hasNext() && time >= (next = read.next())[0]) current = next;

   	    return current[1];
    }
/*
    public double nextTime() {
        double[] next = schedule.peekFirst();
        
        return (next != null) ? next[0] : 0;
    }
    
    public double nextValue() {
        double[] next = schedule.peekFirst();
        
        return (next != null) ? next[1] : 0;
    }*/
    
    // Returns true if the control actions list is ordered by time, false if not
    public boolean ordered() {
    	Iterator<double[]> iter = schedule.iterator();
    	double currentTime, nextTime; 
    	
    	if(!iter.hasNext()) return true;
    	
    	nextTime = iter.next()[0];
		while(iter.hasNext()){
    		currentTime = nextTime;
    		nextTime = iter.next()[0];
    		if(currentTime > nextTime) return false;
    	}
    	
    	return true;
    }
}
